package com.cloudbroker.bcs.platform.dav.configure.service;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cloudbroker.bcs.common.configure.ConfigUtil;
import com.cloudbroker.bcs.common.configure.HSBCSZooKeeperConfigurator;
import com.cloudbroker.bcs.common.zookeeper.ZooKeeperClient;

public class PersistenceService {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(PersistenceService.class);
    
    private static HSBCSZooKeeperConfigurator zkConfigurator;
    
    public static void init(String zookeeperConnectString) {
        ZooKeeperClient zkClient = new ZooKeeperClient(zookeeperConnectString);
        zkClient.start();
        zkConfigurator = new HSBCSZooKeeperConfigurator(zkClient);
    }
    
    public static void init(ZooKeeperClient zkClient) {
        zkConfigurator = new HSBCSZooKeeperConfigurator(zkClient);
    }
    
    public static void init(HSBCSZooKeeperConfigurator zkConfigurator) {
        PersistenceService.zkConfigurator = zkConfigurator;
    }
    
    public static void dispose() {
        if (null != zkConfigurator) {
            zkConfigurator.dispose();
        }
    }
    
    public static void saveConfigDataToZooKeeper(String category, String tenantId, Map<String, Object> configuration) {
        if (null != zkConfigurator) {
            if (StringUtils.isNotBlank(category) && StringUtils.isNotBlank(tenantId)) {
                zkConfigurator.getHSBCSConfigWriter(category, tenantId).setConfiguration(configuration);
            }
        } else {
            LOGGER.warn("no zkConfigurator exists, will not write to zookeeper");
        }
    }
    
    public static void saveConfigDataToZooKeeper(String category, String tenantId, Properties configuration) {
        if (null != zkConfigurator) {
            if (StringUtils.isNotBlank(category) && StringUtils.isNotBlank(tenantId)) {
                zkConfigurator.getHSBCSConfigWriter(category, tenantId).setConfiguration(configuration);
            }
        } else {
            LOGGER.warn("no zkConfigurator exists, will not write to zookeeper");
        }
    }
    
    public static Map<String, Object> getConfigDataFromZooKeeper(String category, String tenantId) {
        Map<String, Object> map = null;
        if (null != zkConfigurator) {
            if (StringUtils.isNotBlank(category) && StringUtils.isNotBlank(tenantId)) {
                map = zkConfigurator.getHSBCSConfigReader(category, tenantId).getConfiguration();
            }
        } else {
            LOGGER.warn("no zkConfigurator exists, will not write to zookeeper");
        }
        if (null == map) {
            map = new HashMap<String, Object>();
        }
        return map;
    }
    
    private static Connection getConnection() throws Exception {
        String driver = ConfigUtil.get("db.driverClassName");
        String url = ConfigUtil.get("db.url");
        String name = ConfigUtil.get("db.username");
        String password = ConfigUtil.get("db.password");

        url = url + "?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false";
        LOGGER.info("driver:" + driver + ", url:" + url + ", username:" + name + ", password:"
                + (null == password ? "" : password.replaceAll(".", "*")));
        Connection conn = null;
        if (StringUtils.isNotBlank(driver) && StringUtils.isNotBlank(url)) {
            try {
                Class.forName(driver);
                conn = DriverManager.getConnection(url, name, password);
            } catch (Exception e) {
                LOGGER.error("getConnection failed", e);
            }
        }
        return conn;
    }
    
    public static Map<Object, Object> loadAllOriConfigDataFromDB() {
        Map<Object, Object> params = new HashMap<Object, Object>();
        PreparedStatement pstmt = null;
        Connection conn = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            if (conn != null) {
                pstmt = conn.prepareStatement("SELECT SYS_CONF_ID, SYS_CONF_KEY, SYS_CONF_VALUE FROM SYS_CONFIG");
                rs = pstmt.executeQuery();
                while (rs.next()) {
                    params.put(rs.getString("SYS_CONF_KEY"), rs.getString("SYS_CONF_VALUE"));
                }
            }
        } catch (Exception e) {
            LOGGER.error("获取配置数据异常", e);
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return params;
    }
    
    public static int saveOriConfigDataToDB(Map<String, String> params) {
        PreparedStatement pstmt = null;
        Connection conn = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            if (conn != null) {
                Iterator<Map.Entry<String, String>> iter = params.entrySet().iterator();
                while (iter.hasNext()) {
                    Map.Entry<String, String> entry = iter.next();
                    pstmt = conn
                            .prepareStatement("SELECT SYS_CONF_KEY, SYS_CONF_VALUE FROM SYS_CONFIG WHERE SYS_CONF_KEY=?");
                    pstmt.setString(1, entry.getKey());
                    rs = pstmt.executeQuery();
                    
                    String updateSQL = null;
                    if (rs.next()) {
                        String itemValue = rs.getString("SYS_CONF_VALUE");
                        if (itemValue == null || !itemValue.equals(entry.getValue())) {
                            updateSQL = "UPDATE SYS_CONFIG SET SYS_CONF_VALUE=? WHERE SYS_CONF_KEY=?";
                        }
                    } else {
                        updateSQL = "INSERT INTO SYS_CONFIG(SYS_CONF_VALUE, SYS_CONF_KEY) VALUES (?, ?)";
                    }
                    rs.close();
                    pstmt.close();
                    
                    if (null != updateSQL) {
                        pstmt = conn.prepareStatement(updateSQL);
                        pstmt.setString(1, entry.getValue());
                        pstmt.setString(2, entry.getKey());
                        pstmt.executeUpdate();
                    }
                }
            } else {
                return -1;
            }
        } catch (Exception e) {
            LOGGER.error("保存数据出错", e);
            return -2;
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return 0;
    }
    
}
